package system

import (
	"strconv"

	"gitee.com/sansaniot/ssiot-core/facade/env"
	"gitee.com/sansaniot/ssiot-core/facade/runtime"
	"gitee.com/sansaniot/ssiot-core/logger"
	"github.com/bytedance/sonic"

	"ssalarm/common/constant"
	"ssalarm/common/enums"
	mq "ssalarm/common/middleware/mqtt"
	"ssalarm/common/utils"
	"ssalarm/internal/alarm/models"
	"ssalarm/internal/alarm/service"
	"ssalarm/internal/data/action"
	"ssalarm/internal/data/partition"
	"ssalarm/internal/data/thread"
	"ssalarm/internal/task"
)

func InitSystemBiz() {
	// 初始告警redis
	initRedisAlarmConfig()
	// 注册业务类
	initRegistryPartition()
	// 启动数据线程
	initDataThread()
	// 启动mqtt客户端
	initMqttClient()
	// 定时任务
	task.Start()
}

func initRedisAlarmConfig() {
	acModel := models.SysAlarmConfig{}
	acModel.Orm = env.Db
	acList := make([]models.SysAlarmConfig, 0)
	if err := acModel.FindList(&acList); err != nil {
		logger.Error(err)
		return
	}
	// 查询之前的缓存
	tmpCountCacheMap := make(map[string]float64)
	for _, config := range acList {
		sn := config.DevSn
		variable := config.Key
		redisKey := constant.AlarmConfigKey + sn
		vb, _ := env.Cache.HashGet(redisKey, variable)
		if len(vb) > 0 {
			confArray := utils.BytesToMapArr([]byte(vb))
			for _, confJson := range confArray {
				triggerType := confJson["triggerType"].(float64)
				warningMode := utils.GetIntValueFiled(confJson, "warning_mode")
				tmpCount := float64(0)
				if _, ok := confJson["tmpCount"]; ok {
					tmpCount = confJson["tmpCount"].(float64)
				}
				if triggerType == 1 && tmpCount > 0 {
					ck := sn + "|" + variable + "|" + strconv.Itoa(warningMode)
					tmpCountCacheMap[ck] = tmpCount
				}
			}
		}
	}

	devConfig := make(map[string]map[string]interface{})
	for _, alarmConfig := range acList {
		redisWarn := make([]map[string]interface{}, 0)
		service.GenRedisWarn(&redisWarn, utils.BytesToMapArr(alarmConfig.Warning))
		// 还原首次告警缓存
		for _, m := range redisWarn {
			triggerType := m["triggerType"].(float64)
			warningMode := utils.GetIntValueFiled(m, "warning_mode")
			if triggerType != 1 {
				continue
			}
			ck := alarmConfig.DevSn + "|" + alarmConfig.Key + "|" + strconv.Itoa(warningMode)
			if tmpCount, ok := tmpCountCacheMap[ck]; ok {
				m["tmpCount"] = tmpCount
			}
		}
		bytes, _ := sonic.Marshal(redisWarn)
		redisWarnStr := string(bytes)
		if _, ok := devConfig[alarmConfig.DevSn]; !ok {
			devConfig[alarmConfig.DevSn] = make(map[string]interface{})
		}
		devConfig[alarmConfig.DevSn][alarmConfig.Key] = redisWarnStr
	}
	for devSn, config := range devConfig {
		if err := env.Cache.HashSet(constant.AlarmConfigKey+devSn, config); err == nil {
			constant.HasAlarmConfigSn.Store(devSn, devSn)
		}
	}
	logger.Info("初始同步告警配置缓存.")
}

func initRegistryPartition() {
	// 获取db
	db := runtime.Runtime.GetDbByKey("db")
	if db == nil {
		return
	}
	// ssdevice已处理数据接收
	partition.Registry(enums.Handler.Get().Name, &action.Handle{Orm: db})
	// ssdevice设备删除广播
	partition.Registry(enums.Broadcast.Get().Name, &action.Broad{Orm: db})

}

func initDataThread() {
	//设备告警状态更新
	thread.SyncDevAlarmThread{}.Run("SyncDevAlarmThread")
}

func initMqttClient() {
	mq.MqttClient = mq.NewClient()
	// 固定订阅主题
	mq.MqttClient.InitSubscribe(constant.HandledMsgTopic, mq.TopicHandler)
	mq.MqttClient.InitSubscribe(constant.DeviceDeleteMsgTopic, mq.TopicHandler)
	mq.MqttClient.InitSubscribe(constant.DeviceAddMsgTopic, mq.TopicHandler)
	if _, err := mq.MqttClient.CreateClient(); err != nil {
		logger.Error("mqtt连接失败" + err.Error())
	}
}
